﻿using System;
using System.Diagnostics;
using System.IO;
using System.IO.IsolatedStorage;
using System.Windows;
using GalaSoft.MvvmLight.Messaging;
using JustinAngel.Neurons.Framework;
using JustinAngel.Neurons.Framework.Helpers;
using JustinAngel.Neurons.Framework.Messages;
using JustinAngel.Neurons.Framework.Services;
using JustinAngel.UnitedNationsNews.Framework;
using JustinAngel.UnitedNationsNews.ServerModel;
using Microsoft.Devices;
using Microsoft.Phone.Shell;
using Newtonsoft.Json;
using Ninject;
using Environment = System.Environment;

namespace JustinAngel.UnitedNationsNews.Services
{
    public class DataService : IAppService, IDataService
    {
        public const string PipeUrl = "http://pipes.yahoo.com/pipes/pipe.run?_id=85d85a206ac5032a0023f03c38f67b67&_render=json";

        [Inject]
        public IWebRequestMaker WebRequestMaker { get; set; }

        [Inject]
        public IDialogService DialogService { get; set; }

        [Inject]
        public IIsolatedStorageHelper IsolatedStorageHelper { get; set; }

        [Inject]
        public IRssItemsToViewModelsTransformer RssItemsToViewModelsTransformer { get; set; }

        // this has to be static due to lifecycle issues
        public static bool HasCachedWebRequestResult
        {
            get
            {
//#if DEBUG
//                // always return false when running in debug on a device
//                // we want to see the initialization sequence from scratch
//                if (Microsoft.Devices.Environment.DeviceType == DeviceType.Device)
//                {
//                    return false; 
//                }
//#endif
                return IsolatedStorageSettings.ApplicationSettings.Contains("LastRssWebRequestResult");
            }
        }

        private static RootModel _RootModel;
        public RootModel RootModel
        {
            get { return _RootModel; }
            set
            {
                _RootModel = value;
                IoC.Get<IMessenger>().Send(new RootModelChangedMessage(value));
            }
        }

        public RssRootItem _RssRootItem;

        private string LastRssWebRequestResult
        {
            get
            {
                return (string)IsolatedStorageHelper.GetSetting("LastRssWebRequestResult");
            }
            set { IsolatedStorageHelper.SetSetting("LastRssWebRequestResult", value); }
        }

        public void StartService()
        {
            WebRequestMaker.StartWithCredentialsAndTimeout(PipeUrl, TimeSpan.FromSeconds(30),
                OnSeccessfulWebRequest,
                () => DispatcherHelper.BeginInvokeOnUIThreadAtEndOfQueue(OnFailedWebRequest));

            OnApplicationActivated();

            IoC.Get<IMessenger>().Register<ApplicationDeactivatedMessage>(this, OnApplicationDecativated);

            IoC.Get<IMessenger>().Register<ApplicationActivatedMessage>(this, OnApplicationActivated);
        }

        private void OnApplicationActivated(ApplicationActivatedMessage obj = null)
        {
            if (!HasCachedWebRequestResult)
                return;

            if (RootModel != null)
                return;

            SetRootItem();
        }

        private void OnApplicationDecativated(ApplicationDeactivatedMessage obj)
        {
        }

        private void OnFailedWebRequest()
        {
            if (!HasCachedWebRequestResult)
            {
                DispatcherHelper.BeginInvokeOnUIThreadAtEndOfQueue(() => 
                {
                    DialogService.ShowMessageBox("We couldn't get news to display in the app. Please open the app back up again when there's network connectivity.",
                                 "We're sorry",
                                 MessageBoxButton.OK);
                    throw new ApplicationExitException();
                });
            }
            else
            {
                DispatcherHelper.BeginInvokeOnUIThreadAtEndOfQueue(() => 
                {
                    DialogService.ShowMessageBox("We couldn't get the latest news to display in the United Nations News app. You can still view archived news articles.",
                                 "We're sorry",
                                 MessageBoxButton.OK);
                    if (Debugger.IsAttached)
                    {
                        Debugger.Break();
                    }
                });
            }
        }

        private void OnSeccessfulWebRequest(Stream resultStream)
        {
            LastRssWebRequestResult = resultStream.ReadToEnd();

            SetRootItem();
        }

        private void SetRootItem()
        {
            _RssRootItem = DeserializeStreamToBusinessObject(LastRssWebRequestResult);
            RootModel = RssItemsToViewModelsTransformer.Transform(_RssRootItem);
        }

        public static RssRootItem DeserializeStreamToBusinessObject(string rssWebRequestResult)
        {
            return JsonConvert.DeserializeObject<RssRootItem>(rssWebRequestResult);
        }

        public void StopService()
        {
        }

        public void WithRootModel(Action<RootModel> action)
        {
            if (RootModel != null)
            {
                action(RootModel);
            }
            else
            {
                IoC.Get<IMessenger>().Register<RootModelChangedMessage>(this,
                    msg => action(msg.Content));
            }
        }
    }
}
